<template>
  <el-card v-if="classifyList.length > 0" id="left-nav__bar" :class="{'top':isFixed}" class="border-radius box-shadow">
    <el-menu :default-active="active">
      <el-menu-item @click="scrollTo(index)" :index="(index) + ''" v-for="(item,index) in navList" :key="index" v-if="item.classifyStatus != '2'">
        <i class="el-icon-menu"></i>
        <span slot="title">{{ item.classifyName }}</span>
      </el-menu-item>
    </el-menu>
  </el-card>
</template>

<script>
import { mapState } from "vuex";
export default {
  computed: {
    ...mapState({
      isLogin: state => state.user.isLogin,
      classifyList: state => state.classifyList
    })
  },
  data(){
    return{
      // 目标元素与整个网页顶部间的距离
      targetTop: 0,
      //是否吸顶
      isFixed: false,
      //选中
      active: "0",
      //导航列表
      navList: []
    }
  },
  mounted(){
    if(this.isLogin){
      this.navList.push({classifyName: "我的收藏"});
    }
    this.classifyList.forEach(value => {
      this.navList.push(value);
    });
    if(this.classifyList.length > 0){
      // 监听页面滚动事件
      window.addEventListener('scroll', this.handleScroll, false);
      // 获取目标元素与整个网页顶部间的距离
      this.targetTop = document.querySelector('#left-nav__bar').offsetTop;
    }
  },
  destroyed() {
    // 必须移除监听器，不然当该vue组件被销毁了，监听器还在就会出错
    window.removeEventListener('scroll', this.handleScroll);
  },
  methods: {
    handleScroll(e) {
      let scrollTop = e.target.scrollTop || window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop // 滚动条偏移量
      //吸顶事件
      this.isFixed = scrollTop > this.targetTop;
      for (let i = 0; i < this.navList.length; i++) {
        if (scrollTop - 415 >= document.querySelector("#navBar" + i).offsetTop) {
          this.active = i + "";
        }
      }
    },
    // 跳转到指定索引的元素
    scrollTo(index) {
      // 获取目标的 offsetTop
      const targetOffsetTop = document.querySelector("#navBar" + index).offsetTop + 415;
      // 获取当前 offsetTop
      let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
      // 定义一次跳 50 个像素，数字越大跳得越快，但是会有掉帧得感觉，步子迈大了会扯到蛋
      const STEP = 10;
      // 判断是往下滑还是往上滑
      if (scrollTop > targetOffsetTop) {
        // 往上滑
        smoothUp();
      } else {
        // 往下滑
        smoothDown();
      }
      // 定义往下滑函数
      function smoothDown() {
        // 如果当前 scrollTop 小于 targetOffsetTop 说明视口还没滑到指定位置
        if (scrollTop < targetOffsetTop) {
          // 如果和目标相差距离大于等于 STEP 就跳 STEP
          // 否则直接跳到目标点，目标是为了防止跳过了。
          if (targetOffsetTop - scrollTop >= STEP) {
            scrollTop += STEP;
          } else {
            scrollTop = targetOffsetTop;
          }
          document.body.scrollTop = scrollTop + 1;
          document.documentElement.scrollTop = scrollTop + 1;
          // 关于 requestAnimationFrame 可以自己查一下，在这种场景下，相比 setInterval 性价比更高
          requestAnimationFrame(smoothDown);
        }
      }
      // 定义往上滑函数
      function smoothUp() {
        if (scrollTop > targetOffsetTop) {
          if (scrollTop - targetOffsetTop >= STEP) {
            scrollTop -= STEP;
          } else {
            scrollTop = targetOffsetTop;
          }
          document.body.scrollTop = scrollTop + 1;
          document.documentElement.scrollTop = scrollTop + 1;
          requestAnimationFrame(smoothUp);
        }
      }
    }
  }
}
</script>

<style scoped>
#left-nav__bar{
  position: absolute;
  right: calc(50% + 3px);
  margin-right: 610px;
  z-index: 10;
  width: 150px;
  background-color: #FFFFFF;
  padding: 0;
  margin-top: 20px;
}
.top{
  position: fixed !important;
  top: 0;
}
</style>

<style>
#left-nav__bar .el-card__body{
  padding: 0;
}
#left-nav__bar .el-menu{
  border: none
}
#left-nav__bar .el-menu-item{
  height: 36px;
  line-height: 36px;
}
#left-nav__bar .is-active{
  background-color: #ECF5FF;
}
</style>
